package com.zhuhjay;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Property;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

/**
 * @author ZhuHJay
 * @date 2023/1/11 13:08
 */
public class MybatisPlusGenerator {
    /** 文件输出的路径 */
    private static final String OUT_DIR_PATH =
            System.getProperty("user.dir") + "/src/main/java";
    /** 数据库连接信息 */
    private static final String MYSQL_URL_PREFIX = "jdbc:mysql://";
    private static final String MYSQL_URL_SUFFIX =
                    "?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&serverTimezone=UTC";
    /** 需定制的数据信息 */
    private static final String HOST = "localhost";
    private static final String PORT = "3306";
    private static final String DATABASE = "generic";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";

    public static void main(String[] args) {
        FastAutoGenerator
                .create(getDataSourceConfig())
                .globalConfig(MybatisPlusGenerator::getGlobalConfig)
                .packageConfig(MybatisPlusGenerator::getPackageConfig)
                .strategyConfig(MybatisPlusGenerator::getStrategyConfig)
                .templateConfig(MybatisPlusGenerator::getTemplateConfig)
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板，默认的是Velocity引擎模板
                .execute();
    }

    protected static DataSourceConfig.Builder getDataSourceConfig(){
        return new DataSourceConfig.Builder(getMysqlUrl(), USERNAME, PASSWORD);
    }

    private static String getMysqlUrl() {
        return MYSQL_URL_PREFIX + HOST + ':' + PORT + '/' + DATABASE + MYSQL_URL_SUFFIX;
    }

    protected static void getGlobalConfig(Function<String, String> scanner, GlobalConfig.Builder builder){
        builder.outputDir(OUT_DIR_PATH) // 指定输出目录
                .disableOpenDir()
                .author("Zhuhjay") // 	作者名
                .enableSwagger() // 开启 swagger 模式
                .dateType(DateType.ONLY_DATE) // 时间策略
                .commentDate("yyyy-MM-dd") // 注释日期
                .build();
    }

    protected static void getPackageConfig(Function<String, String> scanner, PackageConfig.Builder builder){
        builder.parent("com.zhuhjay") // 父包名
                //.moduleName(scanner.apply("请输入存放的父包模块名 eg: system")) // 父包模块名
                .entity("model.entity") // Entity 包名
                .service("service") // Service 包名
                .serviceImpl("service.impl") // Service Impl 包名
                .mapper("mapper") // Mapper 包名
                .xml("mapper.xml") // Mapper XML 包名
                .controller("controller") // Controller 包名
                .build();
    }

    protected static void getTemplateConfig(TemplateConfig.Builder builder){
        builder
                .entity("/templates/entity.java") // 设置实体模板路径(JAVA)
                .service("/templates/service.java") // 设置 service 模板路径
                .serviceImpl("/templates/serviceImpl.java") // 设置 serviceImpl 模板路径
                .mapper("/templates/mapper.java") // 设置 mapper 模板路径
                .controller("/templates/controller.java") // 设置 controller 模板路径
                .build();
    }

    protected static void getStrategyConfig(Function<String, String> scanner, StrategyConfig.Builder builder){
        builder.enableCapitalMode() // 	开启大写命名
                .enableSkipView() // 开启跳过视图
                .disableSqlFilter() // 禁用 sql 过滤
                .addInclude(getTables(scanner.apply("请输入表名，多个英文逗号分隔？所有输入 all"))) // 增加表匹配(内存过滤)
                // 实体设置
                .entityBuilder()
                .enableLombok()
                .enableChainModel()
                .enableTableFieldAnnotation()
                .logicDeletePropertyName("deleted")
                .idType(IdType.AUTO)
                .addTableFills(new Property("createTime", FieldFill.INSERT))
                .addTableFills(new Property("loginTime", FieldFill.INSERT_UPDATE))
                .addTableFills(new Property("operTime", FieldFill.INSERT))
                // 控制器设置
                .controllerBuilder()
                .enableRestStyle()
                // 业务设置
                .serviceBuilder()
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImpl")
                .build();
    }

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}
